package com.icexxx.litchi;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

public class HttpServer {
    public static void start(int port) {
        ServerSocket serverSocket = null;
        try {
            serverSocket = new ServerSocket(port);
        } catch (BindException e) {
            if ("Address already in use: JVM_Bind".equals(e.getMessage())) {
                System.out.println("端口[" + port + "]被占用");
                return;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        while (true) {
            Socket acceptTemp = null;
            try {
                Socket accept = serverSocket.accept();
                acceptTemp = accept;
            } catch (IOException e) {
                e.printStackTrace();
            }
            final Socket acceptFinal = acceptTemp;
            new Thread() {
                public void run() {
                    InputStream inputStream = null;
                    OutputStream outputStream = null;
                    try {
                        inputStream = acceptFinal.getInputStream();
                        outputStream = acceptFinal.getOutputStream();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                    String line = null;
                    long timeStart = System.currentTimeMillis();
                    int duration = 1000;
                    while (System.currentTimeMillis() - timeStart < duration) {
                        try {
                            line = bufferedReader.readLine();
                            if (line != null && !"".equals(line)) {
                                break;
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        try {
                            Thread.sleep(10);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    if (line != null) {
                        String[] parts = line.split("\\s+");
                        if (parts != null && parts.length >= 3) {
                            String url = parts[1];
                            if ("/favicon.ico".equals(url)) {

                            } else {
                                PrintWriter pr = new PrintWriter(outputStream);
                                pr.print(dataGen());
                                pr.flush();
                                try {
                                    acceptFinal.close();
                                } catch (IOException e) {
                                    e.printStackTrace();
                                }
                                String requestLine = requestLine();
                                if (requestLine.equals(line)) {
                                    System.exit(0);
                                }
                            }
                        }
                    }
                }
            }.start();
        }
    }

    private static String dataGen() {
        final String nl = "\r\n";
        StringBuilder sb = new StringBuilder();
        sb.append("HTTP/1.1 200" + nl);
        sb.append("Content-Type: application/json;charset=UTF-8" + nl);
        sb.append("Date: " + getGMTTime() + nl);
        sb.append("Keep-Alive: timeout=60" + nl);
        sb.append("Connection: keep-alive" + nl);
        String message = "{\"code\":777,\"message\":\"--[正在部署...]--\"}";
        try {
            sb.append("Content-Length: " + message.getBytes("UTF-8").length + nl);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        sb.append(nl);
        try {
            String osName = System.getProperty("os.name").toLowerCase();
            if (osName != null && osName.startsWith("windows")) {
                sb.append(new String(message.getBytes("UTF-8"), "GBK") + nl);
            } else {
                sb.append(message + nl);
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        sb.append(nl);
        return sb.toString();
    }

    private static String getGMTTime() {
        final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss", Locale.ENGLISH);
        TimeZone timeZone = TimeZone.getTimeZone("GMT");
        simpleDateFormat.setTimeZone(timeZone);
        return simpleDateFormat.format(new Date()) + " GMT";
    }

    private static String requestLine() {
        return param(hex(wholeString()));
    }

    private static String wholeString() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String date = sdf.format(new Date());
        String salt = "<<litchi>>";
        String cmd = "shutdown";
        StringBuilder sb = new StringBuilder();
        sb.append(salt);
        sb.append(date);
        sb.append(cmd);
        String wholeString = sb.toString();
        return wholeString;
    }

    private static String param(String str) {
        StringBuilder sb = new StringBuilder("POST /");
        sb.append(str);
        sb.append(" HTTP/1.1");
        return sb.toString();
    }

    private static String hex(String str) {
        if (str == null || "".equals(str)) {
            return "";
        }
        byte[] bys = null;
        try {
            bys = str.getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return hex(bys);
    }

    private static String hex(byte[] bys) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < bys.length; i++) {
            byte byteCur = bys[i];
            String hexString = Integer.toHexString(byteCur);
            sb.append(hexString);
        }
        return sb.toString();
    }
}
